package com.jd.event;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author luolishu
 * 
 */
public class EventTrigger {

	static final Map<String, ExecutorService> treadPoolMaps = new HashMap<String, ExecutorService>();
	static final Map<String, List<EventListener>> listenersMap = new HashMap<String, List<EventListener>>();
	static final EventListener scheduledEventListener=new ScheduledEventListener();
	public EventTrigger() {

	}

	public static void addListeners(String group,
			List<EventListener> eventListeners) {
		List<EventListener> listeners = null;
		if (listenersMap.containsKey(group)) {
			listeners = listenersMap.get(group);
		} else {
			listeners = new ArrayList<EventListener>();
		}
		listeners.addAll(eventListeners);
		listenersMap.put(group, listeners);
	}

	public static void addListener(String group, EventListener eventListener) {
		List<EventListener> listeners = null;
		if (listenersMap.containsKey(group)) {
			listeners = listenersMap.get(group);
		} else {
			listeners = new ArrayList<EventListener>();
		}
		listeners.add(eventListener);
		listenersMap.put(group, listeners);
	}

	public static void addGroup(String group) {
		if (treadPoolMaps.containsKey(group)) {
			return;
		}
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		treadPoolMaps.put(group, threadPool);
		threadPool.submit(new EventConsumerTask(group));
	}

	public static void addGroup(String group, ExecutorService threadPool) {
		if (treadPoolMaps.containsKey(group)) {
			return;
		}
		treadPoolMaps.put(group, threadPool);
		threadPool.submit(new EventConsumerTask(group));
	}

	static public class EventConsumerTask implements Runnable {
		String group;

		public EventConsumerTask(String group) {
			this.group = group;
		}

		@Override
		public void run() {
			final DelayQueue<EventTarget> targetQueues = ScheduedEventReposity.queuesMap
					.get(group);

			while (true) {
				try {
					final EventTarget target = targetQueues.take();
					if (target != null) {
						if(target.getEvent() instanceof ScheduledEventObject){
							scheduledEventListener.listen(target.getEvent());
							continue;
						}
						List<EventListener> listeners = listenersMap.get(group);
						for (final EventListener listener : listeners) {
							if (listener instanceof ThreadPoolEventListener) {
								((ThreadPoolEventListener) listener)
										.getThreadPool().submit(new Runnable() {
											public void run() {
												listener.listen(target
														.getEvent());
											}
										});
							} else {
								listener.listen(target.getEvent());
							}

						}
					}

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
	}

}
